package com.scj.vue3springboot.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scj.vue3springboot.constant.JwtConstant;
import com.scj.vue3springboot.entity.SysUser;
import com.scj.vue3springboot.exception.RRException;
import com.scj.vue3springboot.service.SysUserService;
import com.scj.vue3springboot.util.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Class CustomInterceptor
 * @Author ShiChaojie
 * @Email:scj0725@qq.com
 * 自定义的拦截器类 - 实现 HandlerInterceptor 接口
 */
@Component
@Slf4j
public class CustomInterceptor implements HandlerInterceptor {

    @Autowired
    private SysUserService sysUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        log.info("请求拦截器 - 在请求处理之前调用");
        // 在这里编写拦截逻辑，类似过滤器
        if (shouldBypass(request)) {
            return true;
        } else {
            if (isValidToken(request)) {
                return true;
            } else {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.getWriter().write("Token失效，请重新登录");
                return false;
            }
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        log.info("请求拦截器 - 在请求处理之后调用，但在视图被渲染之前");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//        log.info("请求拦截器 - 在请求处理完成后调用");
    }

    // 自定义放行逻辑，例如针对某些接口放行
    private boolean shouldBypass(HttpServletRequest request) {
        //放行登录接口和注册接口以及验证码接口以及swagger接口
        String uri = request.getRequestURI();
        if (uri.contains("/user/login") ||
                uri.contains("/user/register") ||
                uri.contains("/captcha") ||
                uri.contains("/error") ||

                // swagger资源
                uri.contains("/swagger") ||
                uri.contains("/v2/api-docs") ||
                uri.contains("/doc.html") ||
                uri.contains("/webjars") ||
                uri.contains("/swagger-resources") ||
                uri.contains("/favicon.ico")
        ) {
            return true;
        }
        // 在这里实现放行逻辑
        return false;
    }

    // 自定义 Token 验证逻辑
    private boolean isValidToken(HttpServletRequest request) {
        // 在这里实现 Token 验证逻辑
        //获取请求头中的token
        String jwt = request.getHeader("token");
        log.info("token:{}", jwt);
        //判断token是否为空
        if(!StringUtils.isNotBlank(jwt)){
            return false;
        }
        int errCode = JwtUtils.validateJWT(jwt).getErrCode();
        if (errCode== JwtConstant.JWT_ERRCODE_NULL){
            log.info("Token不存在");
            throw new RRException("Token不存在");
        }else if (errCode==JwtConstant.JWT_ERRCODE_EXPIRE){
            log.info("Token过期");
            throw new RRException("Token过期");
        }else if (errCode== JwtConstant.JWT_ERRCODE_FAIL){
            log.info("验证不通过");
            throw new RRException("验证不通过");
        }else if (errCode==JwtConstant.JWT_ERRCODE_SUCCESS){
            log.info("jwt验证结果：验证通过");
        }

        //通过之后获取username
        Claims claims =JwtUtils.validateJWT(jwt).getClaims();
        String username=null==claims?"":claims.getSubject();

        SysUser users = sysUserService.getOne(new QueryWrapper<SysUser>().eq("user_name",username));
        if (null == users) {
            return false;
        }
        return true; // 你的验证逻辑
    }
}
